/*
 *
 * Copyright 2007, 2008 Tiberiumlabs
 *
 * This file is part of Tiberiumlabs Lailaps.
 *
 * Tiberiumlabs Lailaps is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tiberiumlabs Lailaps is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.tiberiumlabs.lailaps.threads.threaded;

import java.io.File;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.tiberiumlabs.lailaps.Mediator;
import org.tiberiumlabs.lailaps.actions.events.DataEvent;
import org.tiberiumlabs.lailaps.actions.events.DataListener;
import org.tiberiumlabs.lailaps.gui.GUIBuilder;
import org.tiberiumlabs.lailaps.gui.elements.ColumnPositions;
import org.tiberiumlabs.lailaps.list.DownloadItem;
import org.tiberiumlabs.lailaps.list.DownloadsListModel;

/**
 *
 * step 1 - prepare output channel
 * step 2 - execute first GetMethod
 * step 3 - parse head of GetMethod to determine if we can do multiple connections
 * step 4 - start some quantity of connections with calculated offsets
 *
 * * force continue
 * * force redownload
 *
 * @author <a href="paranoid.tiberiumlabs@gmail.com">Paranoid</a>
 */
public class ThreadedDownloadController implements DataListener, ColumnPositions, Comparable<ThreadedDownloadController> {
    
    private static final Log LOG = LogFactory.getLog(ThreadedDownloadController.class);

    // row number of current download item from table
    private int row;

    // table
    private DownloadsListModel model = Mediator.getMediator().getDownloadsListModel();

    // current download item
    private DownloadItem item;

    public void process() {

        // set WAITING status on start

        // set PREPARING status on work start

        // get out item to download

        // determine target file
        /*
         * remember about:
         * - force redownload
         * - force continue
         * - set new file name if changed
         */

        // store file, stream and channel

        // from method factory get protocolFacade

        // get response
        /*
         * if error happened:
         * - set ERROR status
         * - close streams and channels
         * - free all references
         */

        // get full size to be downloaded
        /*
         * - if full size determined and more than XXX - calculate parts
         * - if full size unknown - downloading in 1 thread
         */

        // set WORKING status before starting download

        // start new threads to download with setted offset and channel
        /*
         * when download completes:
         * - set statuses
         * -
         */
    }
    
    private void notifyStart() {
        // TODO implement
    }
    
    private void notifyEnd() {
        // TODO implement
    }
    
    private void prepareOutput() {
        File outputFolder = new File(item.getSafeOutputPath());
        if (!outputFolder.exists()) {
            outputFolder.mkdirs();
        }
        File outputFile = new File(outputFolder, item.getOutputFile());
        /*
         * if output file exists - there are some options
         * - file may be already created and we need to append it
         * - force redownload - we can rename old file and create new file
         * - file just already exists, so we need to choose new name instead of that in item
         */
        if (outputFile.exists()) {
            if (!item.isTargetFileCreated()) {
                
            }
            item.setCompletedSize(outputFile.length());
        }
    }

    public int getRow() {
        return row;
    }
    
    // <editor-fold defaultstate="collapsed" desc=" some common interfaces implemented ">
    
    public void dataChanged(DataEvent event) {
        int newRow = event.calculateCurrentRow(row);
        if (newRow == -1) {
            row = model.indexOfItem(item);
            return;
        }
        row = newRow;
    }

    public int compareTo(ThreadedDownloadController o) {
        return row = o.row;
    }
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc=" downloadsTable updates ">
    
    private GUIBuilder guiBuilder = Mediator.getMediator().getGuiBuilder();

    private long lastUpdate = 0;
    private void updateSpeed() {
        long t = System.currentTimeMillis();
        if (t - lastUpdate >= 240 && guiBuilder.isTableVisible()) {
            // TODO make repaint not in downloading thread, but in some common class like SwingWorker
            guiBuilder.getTable().repaintCells(row, COL_COMPLETED, COL_SPEED, COL_PROGRESS, COL_SIZEPROGRESS, COL_TIMEELAPSED, COL_TIMEESTIMATED);
            lastUpdate = t;
        }
    }
    private void updateTable(int column) {
        if (guiBuilder.isTableVisible()) {
            guiBuilder.getTable().repaintCell(row, column);
        }
    }

    // </editor-fold>

}
